<?php

class Model_Listing_Job extends Model_Listing implements Model_Listing_Interface
{
    const YEAR_EXPERIENCE_MIN = 0;
    const YEAR_EXPERIENCE_MAX = 40;

    const SALARY_MIN = 0;
    const SALARY_MAX = 100;

    protected static  $_collection = 'listing';


    protected static $_requirements = array(
     //   'em'  => array('Required', 'Validator:EmailAddress'), //Email
        'cb'  => array('Array'), //exteriorcolor
        'fl'  => array('Array'), //files
        'jl'  => array('Array'), //joblocation
        'et'  => array('Array'), //employmenttype
        'cl'  => array('Array'), //careerlevel
        'rs'  => array('Array'), //residentstatus
    );

    protected $_category = array();

    public function __construct($data = array(), $config = array()) {
        static::$_transcript = array_merge(array(
            'et' => 'employmenttype',
            'sr' => 'salary',
            'srh' => 'salary_hour',
            'ne' => 'negotiable',
            'jl' => 'joblocation',
            'rs' => 'residentstatus',
            'cl' => 'careerlevel',
            'jf' => 'jobfunction',
            'jc' => 'jobcategory',
            'ye' => 'yearexperience',
            'ed' => 'education',
            'fg' => 'freshgraduate',
            'cb' => 'companybenefits',
            'fl' => 'files',
            'cn_en' => 'company_name_en',
            'cn_tc' => 'company_name_tc',
            'jd_en' => 'job_desc_en',
            'jd_tc' => 'job_desc_tc',
            'tl_en' => 'title_en',
            'tl_tc' => 'title_tc',
         ), static::$_transcript);
        parent::__construct($data, $config);
    }

	public static function getTranslationFormField()
    {
        $arr = array(
			'tl_en' =>'text',
			'cn_en' =>'text',
			'cs_en' =>'textarea',

		);

		return $arr;
    }

    public function postAnAddForm($options = array()) {
        $options = array_merge($options, array('category' => $this->category));
        return new Listing_Form_PostAnAddJobForm($options);
    }

    public function getAdDetailPartialName()
    {
        return 'customization/job.phtml';
    }

    public function getAdPreviewPartialName()
    {
        return $this->getAdDetailPartialName();
    }


    public static function getSearchResultPartialName()
    {
        return 'jobs';
    }

    public static function getRefineSearchForm()
    {
        return new Search_Form_JobRefineForm();
    }

    public static function processRefineSearchForm($page, $per_page, $sort, &$query, &$fields, &$additionalParameters)
    {
        $results = false;
        if(empty($fields)) {
            $fields  = array('description', 'title', 'area_l2_name', 'area_l1_name', 'street');
        }
        if(empty($additionalParameters)) {
            $additionalParameters = array();
        }
        $values  = array();

        $search_terms       = self::getSearchTextTerms();
        $exact_search_terms = self::getExactSeachTerms();


        $q      = '';
        $qq     = !empty($_GET['keyword']) ? $_GET['keyword'] : ( !empty($_GET['jobs']['keyword']) ? $_GET['jobs']['keyword'] : '');
        $to_add = ' ';
        $get    = $_GET;
        $get['keyword'] = !empty($_GET['jobs']['keyword']) ? $_GET['jobs']['keyword'] : (!empty($get['keyword']) ? $get['keyword'] : '');


        //add the username
        if (!empty($get['keyword'])) {
            //$q = '(username_lower:"'.$get['keyword'].'"^50.0) ';
        }

        if (!empty($exact_search_terms) && !empty($get['keyword'])) {
            foreach($exact_search_terms as $name => $val) {
                foreach($val as $k => $v) {
                    if (preg_match('#('.trim($v).')#i', $get['keyword'], $match)) {
                        //var_dump($match, $v, $get['keyword'], str_ireplace( $v, '', $get['keyword']));
                        $get['keyword'] = str_ireplace( $v, '', $get['keyword']);
                        $q .= $to_add.str_replace('_name', '', $name) .':'.$k.'^5.0 ';
                        $to_add = ' OR ';
                    }
                }
            }
            if (!empty($q) && !empty($tmp)) {
                $q = ' OR ('.$tmp.') ';
            }
        }

        $to_add = ' ';

        //remove quoted words and add them to q
        $bak = !empty($get['keyword']) ? trim($get['keyword']) : '';

        if (!empty($get['keyword'])) {
            $arr = preg_match_all('#\"(.*?)\"#i', $get['keyword'], $match);
            foreach ($match[1] as $v) {
                $q .= ' AND "'.$v.'"';
            }
            $get['keyword'] = preg_replace('#"(.*?)"#i', '', $get['keyword']);
        }

        $qf = '';
        foreach($search_terms as $v => $weight) {
            $qf .= $v.'^'.$weight.' ';
        }

        if (!empty($qf)) {
            $additionalParameters['qf'] = $qf;
        }

        if (!empty($qq)) {
            $additionalParameters['qq']   = $qq;
        }

        if (!empty($get['keyword'])) {
            if (!empty($q)) {
                $q.=' OR ';
            }
            $q .='(';
            foreach ($fields as $f) {
                $list = explode(' ', trim($get['keyword']));
                foreach($list as $vl) {
                    if (!empty($vl)) {
                        $q .= $to_add.''.$f.':'.$vl;
                        $to_add = ' OR ';
                    }
                }
            }
            $q.=') ';
        }


        $q.= ' OR _query_:"{!dismax qf=$qf v=$qq}" ';

        if (empty($get['keyword'])) {
            $q = '*:*';
        }

        $query = $q;

        $get['sort'] = empty($get['sort']) ? '' : $get['sort'];

        switch ($get['sort']) {
            case 'highest':
                $sort = 'salary desc';
                break;
            case 'lowest':
                $sort = 'salary asc';
                break;
            case 'rel':
                $sort = 'score desc';
                break;
            case 'recent':
                $sort = 'posted_at desc';
                break;
            default:
                if (!empty($_GET['keyword'])) {
                    $_GET['sort'] = 'rel';
                    $sort         = 'score desc';
                } else {
                    $_GET['sort'] = 'recent';
                    $sort         = 'posted_at desc';
                }
        }

        $additionalParameters['fl']   = '*,score';
        $additionalParameters['sort'] = $sort;

        //Parameters to refine search
        $fq         = '';
        if(!empty($additionalParameters['fq'])) {
            $fq = $additionalParameters['fq'];
        }
        
        $valuesplus = array();

        //Has Image
        if (!empty($get['has_image'])) {
            $valuesplus['has_image'] = true;
        }

        //Force only Cars
        //$valuesplus['type_obj_s'] = 'Model_Listing_Job';
        if(strpos($fq, '+type_obj_s') === false) {
            $valuesplus['type_obj_s'] = 'Model_Listing';
        }


        //Employment Type
        if (!empty($_GET['jobs']['employmenttype'])) {//refinements
            $valuesplus['employmenttype'] = $_GET['jobs']['employmenttype'];
        }
        if (!empty($_GET['employmenttype'])) {//quick search
            $valuesplus['employmenttype'] = $_GET['employmenttype'];
        }

        //Job Location
        if (!empty($_GET['jobs']['joblocation'])) {//refinements
            $valuesplus['joblocation'] = $_GET['jobs']['joblocation'];
        }
        if (!empty($_GET['joblocation'])) {//quick search
            $valuesplus['joblocation'] = $_GET['joblocation'];
        }

        //Career Level
        if (!empty($_GET['jobs']['careerlevel'])) {
            $valuesplus['careerlevel'] = $_GET['jobs']['careerlevel'];
        }

        //Education
        if (!empty($_GET['education'])) {
            $valuesplus['education'] = $_GET['education'];
        }

        if (!empty($get['city'])) {
            $valuesplus['city'] = (int) $_GET['city'];
        }


        //Resident status
        if (!empty($_GET['jobs']['residentstatus'])) {
            $valuesplus['residentstatus'] = $_GET['jobs']['residentstatus'];
        }
/*
                'employmenttype_name'   => self::getEmploymentTypePostAd(),
                'joblocation_name'      => self::getJobLocationPostAd(),
                'careerlevel_name'      => self::getCareerLevelPostAd(),
                'education_name'        => self::getEducationPostAd(),
                'residentstatus_name'   => self::getResidentStatusPostAd(),
                        */
        //Salary
        if (!empty($get['salary'])) {
            $valuesplus['salary']   = $get['salary'];
        }

        //Education
        if (!empty($_GET['jobs']['education'])) {
            $valuesplus['education'] = $_GET['jobs']['education'];
        }

        //Resident Status
        if (!empty($_GET['jobs']['residentstatus'])) {
            $valuesplus['residentstatus'] = $_GET['jobs']['residentstatus'];
        }

        //Years of Experience
        if (isset($get['jobs-yearexperience']) && isset($get['jobs-yearexperience-1'])) {
            $test1 = false;$test2 = false;
            if ($get['jobs-yearexperience-1'] == self::YEAR_EXPERIENCE_MAX) {
                $get['jobs-yearexperience-1'] = '*';
                $test1 = true;
            }
            if ($get['jobs-yearexperience'] == self::YEAR_EXPERIENCE_MIN) {
                $get['jobs-yearexperience'] = '0';
                $test2 = true;
            }
            if (!$test1 || !$test2) {
                $valuesplus['yearexperience'] = '['.$get['jobs-yearexperience'].' TO '.$get['jobs-yearexperience-1'].']';
            }
        }

        foreach($valuesplus as $k => $val) {
            if (is_array($val)) {
                foreach($val as $k2 => $v2) {
                    $valuesplus[$k] = '+'.$k.':'.$v2.' ';
                }
            } else {
                $valuesplus[$k] = '+'.$k.':'.$val.' ';
            }
        }

        if (!empty($valuesplus)) {
            $fq .= implode(' ', $valuesplus);
        }


        $category = '';


        if (!empty($category)) {
            $fq .= $category;
        }

        if (!empty($fq)) {
            $additionalParameters['fq'] = $fq;
        }
    }

    public static function getJobCategory()
    {
        $view = Zend_Registry::get('Zend_View');
        $make = array();
        $attr      = Model_Listing_Attribute::all(array('type' => 'Jobs', 'path' => array('$exists' => 0)))->sort(array('order' => 1, 'name' => 1));

        foreach($attr as $k => $loc) {
            if ($loc->name == "All") {
                $make[0] = $loc->name;
            }
            else {
                $make[(string) $loc->_id] = $loc->name;
            }
        }

        return $make;
    }

    public static function getJobCategoryPostAd()
    {
        $view = Zend_Registry::get('Zend_View');
        $make = array();
        $attr      = Model_Listing_Attribute::all(array('type' => 'Jobs', 'path' => array('$exists' => 0)))->sort(array('order' => 1, 'name' => 1));

        foreach($attr as $k => $loc) {
            if ($loc->name == "All") {
                $make[''] = 'Select';
            }
            else {
                $make[(string) $loc->_id] = $loc->name;
            }
        }

        return $make;
    }

    public static function getJobFunction($id)
    {
        $view = Zend_Registry::get('Zend_View');
        $model = array();
        $attr = Model_Listing_Attribute::all(array('path' => new MongoId($id)))->sort(array('order' => 1, 'name' => 1));
        $model[''] = 'All';

        foreach($attr as $k => $loc) {
            $model[(string) $loc->_id] = $loc->name;
        }
        //exit;
        return $model;
    }

    public static function getJobFunctionPostAd($id)
    {
        $view = Zend_Registry::get('Zend_View');
        $model = array();
        $attr = Model_Listing_Attribute::all(array('path' => new MongoId($id)))->sort(array('order' => 1, 'name' => 1));
        $model[''] = 'Select';

        foreach($attr as $k => $loc) {
            $model[(string) $loc->_id] = $loc->name;
        }
        //exit;
        return $model;
    }

    public static function getEmploymentType($id = null)
    {
        $res = self::getEmploymentTypePostAd();

        if ($id !== null) {
            return $res[$id];
        }
        return $res;
    }

    public static function getEmploymentTypePostAd()
    {
        return array(
            1 => '全职',
            2 => '兼职',
            3 => '临时工',
            4 => '实习',
            5 => '自由工作'
        );
    }
    
    public static function getSalary($id = null)
    {
        $res = self::getSalaryPostAd();

        if ($id !== null) {
            return $res[$id];
        }
        return $res;
    }

    public static function getSalaryPostAd()
    {
        return array(
        	'' => 'Select',
            1 => '1000元以下',
            2 => '1000-2000元',
            3 => '2000-3000元',
            4 => '3000-5000元',
            5 => '5000-8000元',
            6 => '8000-12000元',
            7 => '12000-20000元',
            8 => '20000-25000元',
            9 => '25000元以上'
        );
    }
    
    public static function getSalaryHour($id = null)
    {
        $res = self::getSalaryHourPostAd();

        if ($id !== null) {
            return $res[$id];
        }
        return $res;
    }

    public static function getSalaryHourPostAd()
    {
        return array(
        	'' => 'Select',
            1 => '10元以下',
            2 => '10-20元',
            3 => '20-30元',
            4 => '30-40元',
            5 => '40-50元',
            6 => '50-60元',
            7 => '60-80元',
            8 => '80-100元',
            9 => '100元以上'
        );
    }

    public static function getCareerLevel($id = null)
    {
        $res = self::getCareerLevelPostAd();

        if ($id !== null) {
            return $res[$id];
        }
        return $res;
    }

    public static function getCareerLevelPostAd()
    {
        return array(
            1 => 'Entry Level',
            2 => 'Middle',
            3 => 'Senior',
            4 => 'Top'
        );
    }

    public static function getEducation($id = null)
    {
        $res = self::getEducationPostAd();
        unset($res['']);
        if ($id !== null) {
            return $res[$id];
        }
        return $res;
    }

    public static function getEducationPostAd()
    {
        /*return array(
            '' => 'Select',
            1 => '不限',
            2 => '小学',
            3 => '初中',
            4 => '高中',
            5 => '中专',
            6 => '大专',
            7 => '本科',
            8 => '硕士',
            9 => '博士'
        );*/
        return array(
            '' => 'Select',
            1 => '初中',
            2 => '高中',
            3 => '技校',
            4 => '中专',
            5 => '大专',
			6 => '本科',
            7 => '硕士',
            8 => '博士',
        );
    }

    public static function getJobLocation($id = null)
    {
        $res = self::getJobLocationPostAd();

        if ($id !== null) {
            return $res[$id];
        }
        return $res;
    }

    public static function getJobLocationPostAd()
    {
        return array(
            1 => 'Hong Kong Island',
            2 => 'Kowloon',
            3 => 'New Territories',
            4 => 'Outlying Islands',
            5 => 'Mainland China',
            6 => 'Overseas'
        );
    }

    public static function getResidentStatus($id = null)
    {
        $res = self::getResidentStatusPostAd();
        unset($res[-5]);
        if ($id !== null) {
            return $res[$id];
        }
        return $res;
    }

    public static function getResidentStatusPostAd()
    {
        return array(
            1 => 'Permanent Residents Only',
            2 => 'Anyone with Work Visa',
            3 => 'Work Visa Not Required'
        );
    }

    public static function getYearExperience($id = null)
    {
        $res = array('' => 'All') + self::getYearExperiencePostAd();

        if ($id !== null && !empty($res[$id])) {
            return $res[$id];
        }
        return $res;
    }

    public static function getYearExperiencePostAd()
    {
        return array(
            '' => 'Select',
            1 => '1年以下',
            2 => '1-2年',
            3 => '3-5年',
            4 => '6-7年',
            5 => '8-10年',
            6 => '10年以上',
        );
    }

    public static function getCompanyBenefits($id = null)
    {
        $res = array('' => 'All') + self::getCompanyBenefitsPostAd();

        if ($id !== null && !empty($res[$id])) {
            return $res[$id];
        }
        return $res;
    }

    public static function getCompanyBenefitsPostAd()
    {
        return array(
            1 => 'Dental Insurance',
            2 => 'Double Pay (13 mth pay)',
            3 => 'Family Insurance Coverage',
            4 => 'Education Allowance',
            5 => 'Five-day Work Week',
            6 => 'Free Shuttle Bus',
            7 => 'Gratuity',
            8 => 'Tips',
            9 => 'Housing Allowance',
            10 => 'Medical Insurance',
            11 => 'Overtime Pay',
            12 => 'Performance Bonus',
            13 => 'Transportation Allowance',
            14 => 'Travel Allowance',
            15 => 'Work from Home'
        );
    }

    public static function getNegotiable()
    {
        return array(
            1 => 'Negotiable'
        );
    }



    public static function getSearchTextTerms()
    {
        return array(
            'description'         => '1.0',
            'title'               => '7.0',
            'company_name'        => '7.0',
            'employmenttype_name' => '5.0',
            'joblocation_name'    => '5.0',
            'careerlevel_name'    => '5.0',
            'education_name'      => '5.0',
            'residentstatus_name' => '5.0',
        );
    }


    /*
     * return a list of all the possible values that should be extracted from the keyword search and be specified as exact term
     *
     */
    public static function getExactSeachTerms()
    {
       return array(
                'employmenttype_name'   => self::getEmploymentTypePostAd(),
                'joblocation_name'      => self::getJobLocationPostAd(),
                'careerlevel_name'      => self::getCareerLevelPostAd(),
                'education_name'        => self::getEducationPostAd(),
                'residentstatus_name'   => self::getResidentStatusPostAd(),
           );
    }

    public function getSolrDocument($document = null)
    {
        if (!$document instanceof Apache_Solr_Document) {
            $document = new Apache_Solr_Document();
        }
        $view = Zend_Registry::get('Zend_View');

        //Jobs
        $document->company_name     = $this->company_name;
        if (!empty($this->et)) {
            foreach ((array)$this->et as $data) {
                $document->addField('employmenttype', (string)$data);
                $document->addField('employmenttype_name', self::getEmploymentType($data));
                $document->addField('employmenttype_name',  $view->t(self::getEmploymentType($data), Model_Translate::TC));
            }
        }

        if (!empty($this->sr)) {
            $document->salary           = (int)$this->sr;
        }
        if (!empty($this->srh)) {
            $document->salary_hour      = (int)$this->srh;
        }
        $document->price            = (int)$this->sr;
        $document->negotiable       = (int)$this->ne;

        if (!empty($this->jl)) {
            foreach ((array)$this->jl as $data) {
                $document->addField('joblocation', (string)$data);
                $document->addField('joblocation_name', self::getJobLocation($data));
                $document->addField('joblocation_name',  $view->t(self::getJobLocation($data), Model_Translate::TC));
            }
        }
        if (!empty($this->rs)) {
            foreach ((array)$this->rs as $data) {
                $document->addField('residentstatus', (string)$data);
                $document->addField('residentstatus_name', self::getResidentStatus($data));
                $document->addField('residentstatus_name',  $view->t(self::getResidentStatus($data), Model_Translate::TC));
            }
        }
        if (!empty($this->cl)) {
            foreach ((array)$this->cl as $data) {
                $document->addField('careerlevel', (string)$data);
                $document->addField('careerlevel_name', self::getCareerLevel($data));
                $document->addField('careerlevel_name',  $view->t(self::getCareerLevel($data), Model_Translate::TC));
            }
        }
        if (!empty($this->ed)) {
            foreach ((array)$this->ed as $data) {
                $document->addField('education', (string)$data);
                $document->addField('education_name', self::getEducation($data));
                $document->addField('education_name',  $view->t(self::getEducation($data), Model_Translate::TC));
            }
        }

        foreach ((array)$this->ye as $data) {
            $document->addField('yearexperience', (string)$data);
        }

        $document->freshgraduate    = (int)$this->fg;
        foreach ((array)$this->cb as $data) {
            $document->addField('companybenefits', (string)$data);
            $document->addField('companybenefits_name', self::getCompanyBenefits($data));
            $document->addField('companybenefits_name',  $view->t(self::getCompanyBenefits($data), Model_Translate::TC));
        }

        return parent::getSolrDocument($document);
    }


    public static function getSearchResultSort()
    {
        return array(

            'recent' => '最新',
            'rel' => '相关',
            'highest' => '薪水↑',
            'lowest' => '薪水↓',
        );
    }

    public function __get($name)
    {
        if ($name == 'company_name') {
            return  parent::__get('company_name_' . $this->getInternalLanguage());
        } else {
            return parent::__get($name);
        }
    }

    public function __set($name, $arguments) {
        if ($name == 'company_name') {
            return parent::__set('company_name_' . $this->getInternalLanguage(), $arguments);
        } else {
            return parent::__set($name, $arguments);
        }
    }

    public function exportRest($compressed = false)
    {
        $res = parent::exportRest($compressed);
        $view = Zend_Registry::get('Zend_View');

        $res['type'] = 'job';

        if ($compressed) {
            return $res;
        }
        
        
        $res['salary_month'] = !empty($this->salary) ? (string)$this->salary : '';
        $res['salary_hour'] = !empty($this->salaray_hour) ? (string)$this->salary_hour : '';

        unset($res['price']);

        if (!empty($this->jl)) {
            foreach ((array)$this->jl as $data) {
                $res['joblocation'] = (string)$data;
                $res['joblocation_en'] = self::getJobLocation($data);
                $res['joblocation_tc'] =  $view->t(self::getJobLocation($data), Model_Translate::TC);
            }
        }
        if (!empty($this->rs)) {
            foreach ((array)$this->rs as $data) {
                $res['residentstatus'] = (string)$data;
                $res['residentstatus_en'] = self::getResidentStatus($data);
                $res['residentstatus_tc'] =  $view->t(self::getResidentStatus($data), Model_Translate::TC);
            }
        }
        if (!empty($this->cl)) {
            foreach ((array)$this->cl as $data) {
                $res['careerlevel'] = (string)$data;
                $res['careerlevel_en'] = self::getCareerLevel($data);
                $res['careerlevel_tc'] =  $view->t(self::getCareerLevel($data), Model_Translate::TC);
            }
        }
        if (!empty($this->ed)) {
            foreach ((array)$this->ed as $data) {
                $res['education'] = (string)$data;
                $res['education_en'] = self::getEducation($data);
                $res['education_tc'] =  $view->t(self::getEducation($data), Model_Translate::TC);
            }
        }

        foreach ((array)$this->ye as $data) {
            $res['yearexperience'] = (string)$data;
        }


        foreach ((array)$this->cb as $data) {
            $res['companybenefits'] = (string)$data;
            $res['companybenefits_en'] = self::getCompanyBenefits($data);
            $res['companybenefits_tc'] =  $view->t(self::getCompanyBenefits($data), Model_Translate::TC);
        }

        return $res;
    }

    public function processRestForm()
    {
        $post = $_POST;

        //Employment type
        if (!empty($_POST['etype']) && !is_string(self::getEmploymentType($_POST['etype'])) ) {
            throw new Ac_Exception_MissingInformation('Invalid value for employment type');
        }
        if (!empty($_POST['etype'])) {
            $this->employmenttype = $_POST['etype'];
        }

        //Salary
        if (!empty($_POST['salary']) && intval($_POST['salary']) == 0 ) {
            throw new Ac_Exception_MissingInformation('Invalid value for salary');
        }
        if (!empty($_POST['salary'])) {
            $this->salary = $_POST['salary'];
        }


        //Year of experience
        if (!empty($_POST['yoe']) && !is_string(self::getYearExperience($_POST['yoe']))) {
            throw new Ac_Exception_MissingInformation('Invalid value for year of experience');
        }
        if (!empty($_POST['yoe'])) {
            $this->yearexperience = $_POST['yoe'];
        }

        //Job location
        if (!empty($_POST['location'])) {
            $this->joblocation = intval($_POST['location']);
        } else {
            $this->joblocation = range(1, 4); //array_keys(self::getJobLocation());
        }
/*
        if (!empty($_POST['photos'])) {
            $this->photos = array();
            foreach($_POST['photos'] as $k => $photo) {
                if (!empty($photo)) {
                    $res = Ac_Util::downloadPhoto($this->title, $k, $photo, $this->created_at);
                    $tmp = (array) $this->photos;
                    if(!empty($res)) {
                        $tmp[] = $res;
                    }
                    $this->photos = $tmp;
                }
            }
        }
*/        

        //parent::processRestForm();
        return true;
    }
}
